package me.goldze.mvvmhabit.base;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;

import com.afollestad.materialdialogs.MaterialDialog;
import com.trello.rxlifecycle2.components.support.RxFragment;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;

import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment;

import io.reactivex.android.schedulers.AndroidSchedulers;
import me.goldze.mvvmhabit.base.BaseViewModel.ParameterField;
import me.goldze.mvvmhabit.bus.BindingAction;
import me.goldze.mvvmhabit.bus.Messenger;
import me.goldze.mvvmhabit.bus.RxBus;
import me.goldze.mvvmhabit.utils.KLog;
import me.goldze.mvvmhabit.utils.MaterialDialogUtils;

/**
 * Created by goldze on 2017/6/15.
 */
public abstract class BaseFragment<V extends ViewDataBinding, VM extends BaseViewModel> extends RxFragment implements IBaseView {
    protected V binding;
    protected VM viewModel;
    private int viewModelId;
    private MaterialDialog loadingDialog;

    public VM getViewModel() {
        return viewModel;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initParam();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater, initContentView(inflater, container, savedInstanceState), container, false);
        return binding.getRoot();
    }


    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        //解除Messenger注册
        Messenger.getDefault().unregister(viewModel);
        Messenger.getDefault().unregister(this);
        //解除ViewModel生命周期感应
        getLifecycle().removeObserver(viewModel);
        if (viewModel != null) {
            viewModel.removeRxBus();
        }
        if (binding != null) {
            binding.unbind();
        }
    }


    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        //私有的初始化Databinding和ViewModel方法
        initViewDataBinding();
        //私有的ViewModel与View的契约事件回调逻辑
        registorUIChangeLiveDataCallBack();
        //页面数据初始化方法
        initData();
        //页面事件监听的方法，一般用于ViewModel层转到View层的事件注册
        initViewObservable();
//        KLog.e("----------"+getRightTitle());z
        setRightTitle(getRightTitle());
        //注册RxBus
        viewModel.registerRxBus();
    }

    private void setRightTitle(String title) {
        RxBus.getDefault().post(title);
        Messenger.getDefault().register(this, "RightClick", AppCompatTextView.class, view -> {
            onRightEvent(view);
        });

//        RxBus.getDefault().toObservable(getViewLifecycleOwner(), TextView.class)
//                .subscribeOn(AndroidSchedulers.mainThread())
//                .subscribe(view -> {
//                    KLog.e("xxxxxxxxxxxx");
//                    onRightEvent(view);
//                });
    }

    public String getRightTitle() {
        return "";
    }

    public void onRightEvent(View view) {

    }

    @Override
    public boolean getUserVisibleHint() {
        return super.getUserVisibleHint();
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        isViewPagerTag = true;
        this.isVisiable = isVisibleToUser;
        if (viewModel == null)
            return;
        if (isVisibleToUser) {
//            KLog.e("现在展示的界面： [ "+ this+" ] setUserVisibleHint"+ isVisibleToUser);
            if (!isRegister) {
                String cacheKey = getClass().getSimpleName();
                if (!TextUtils.isEmpty(getTag())) {
                    cacheKey += getTag();
                }
//                KLog.e("现在展示的界面： [ "+ cacheKey+" ] setUserVisibleHint");

                viewModel.registerEvent(cacheKey);
            }
        } else {
            isRegister = false;
//            KLog.e("不显示的界面：[ "+ getClass().getSimpleName()+getTag()+" ]");
            viewModel.removeEvent();
        }
    }


    private boolean isViewPagerTag = false;


    private boolean isVisiable = true;

    private boolean isRegister = false;


    @Override
    public void onResume() {
        if (isViewPagerTag) {
            if (isVisiable) {
                isRegister = true;
                String cacheKey = getClass().getSimpleName();
                if (!TextUtils.isEmpty(getTag())) {
                    cacheKey += getTag();
                }
                viewModel.registerEvent(cacheKey);
            }
        } else {
            String cacheKey = getClass().getSimpleName();
            if (!TextUtils.isEmpty(getTag())) {
                cacheKey += getTag();
            }
            viewModel.registerEvent(cacheKey);
        }
//        setRightTitle(getRightTitle());
        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    /**
     * 注入绑定
     */
    private void initViewDataBinding() {
        viewModelId = initVariableId();
        viewModel = initViewModel();
        if (viewModel == null) {
            Class modelClass;
            Type type = getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[1];
            } else {
                //如果没有指定泛型参数，则默认使用BaseViewModel
                modelClass = BaseViewModel.class;
            }
            viewModel = (VM) createViewModel(this, modelClass);
        }
        binding.setVariable(viewModelId, viewModel);
        //支持LiveData绑定xml，数据改变，UI自动会更新
        binding.setLifecycleOwner(this);
        //让ViewModel拥有View的生命周期感应
        getLifecycle().addObserver(viewModel);
        //注入RxLifecycle生命周期
        viewModel.injectLifecycleProvider(this);

    }

    /**
     * =====================================================================
     **/
    //注册ViewModel与View的契约UI回调事件
    protected void registorUIChangeLiveDataCallBack() {
        //加载对话框显示
        viewModel.getUC().getShowLoadingEvent().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String title) {
                showLoadingDialog(title);
            }
        });
        //加载对话框消失
        viewModel.getUC().getDismissLoadingEvent().observe(this, new Observer<Void>() {
            @Override
            public void onChanged(@Nullable Void v) {
                dismissLoadingDialog();
            }
        });
        //跳入新页面
        viewModel.getUC().getStartActivityEvent().observe(this, new Observer<Map<String, Object>>() {
            @Override
            public void onChanged(@Nullable Map<String, Object> params) {
                Class<?> clz = (Class<?>) params.get(ParameterField.CLASS);
                Bundle bundle = (Bundle) params.get(ParameterField.BUNDLE);
                startActivity(clz, bundle);
            }
        });
        //跳入ContainerActivity
        viewModel.getUC().getStartContainerActivityEvent().observe(this, new Observer<Map<String, Object>>() {
            @Override
            public void onChanged(@Nullable Map<String, Object> params) {
                String canonicalName = (String) params.get(ParameterField.CANONICAL_NAME);
                Bundle bundle = (Bundle) params.get(ParameterField.BUNDLE);
                startContainerActivity(canonicalName, bundle);
            }
        });
        //关闭界面
        viewModel.getUC().getFinishEvent().observe(this, new Observer<Void>() {
            @Override
            public void onChanged(@Nullable Void v) {
                NavHostFragment.findNavController(BaseFragment.this).popBackStack();
//                getActivity().finish();
            }
        });
        viewModel.getUC().getFinishActivityEvent().observe(this, new Observer<Void>() {
            @Override
            public void onChanged(@Nullable Void v) {
                getActivity().finish();
            }
        });


        viewModel.getUC().getRemoveFragmentEvent().observe(this, new Observer<Void>() {
            @Override
            public void onChanged(@Nullable Void v) {

            }
        });

        viewModel.getUC().getRefreshEvent().observe(this, new Observer() {
            @Override
            public void onChanged(Object o) {
                refreshLayout();
            }
        });
        //关闭上一层
        viewModel.getUC().getOnBackPressedEvent().observe(this, new Observer<Void>() {
            @Override
            public void onChanged(@Nullable Void v) {
                getActivity().onBackPressed();
            }
        });
        viewModel.getUC().getOnError().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String errorInfo) {
                onError(errorInfo);
                if (tipDialog != null) {
                    tipDialog = tipDialog.getBuilder().title("错误提示！").content(errorInfo).build();
                    tipDialog.show();
                } else {
                    MaterialDialog.Builder builder = MaterialDialogUtils.showBasicDialogNoCancel(getActivity(), "错误提示！", errorInfo);
                    tipDialog = builder.cancelable(false).show();
                }
            }
        });
        viewModel.getUC().getHideKeyboardEvent().observe(this, o -> {
            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
            if (getActivity().getCurrentFocus() != null)
                imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
        });

        viewModel.getUC().getHideRobotLoadingEvent().observe(this, o -> {
            hideRobotLoading();
        });

        viewModel.getUC().getShowRobotLoadingEvent().observe(this, o -> {
            showRobotLoading();
        });

    }

    private MaterialDialog robotLoading;

    public void showRobotLoading() {
        if (robotLoading == null)
            robotLoading = MaterialDialogUtils.showRobotDialog(getActivity());
        if (!robotLoading.isShowing()) {
            robotLoading.show();
        }
    }

    // TODO: 2024/7/16 权宜之计
    public void refreshDialog() {
        try {
            if (robotLoading != null && robotLoading.isShowing())
                robotLoading.dismiss();
        } catch (Exception e) {
            e.printStackTrace();
        }
        robotLoading = MaterialDialogUtils.showRobotDialog(getActivity());
    }

    public void hideRobotLoading() {
        if (robotLoading != null && robotLoading.isShowing())
            robotLoading.dismiss();
    }

    private MaterialDialog tipDialog;

    public void showLoadingDialog(String title) {
        if (loadingDialog != null) {
            if (!loadingDialog.isShowing()) {
                loadingDialog.show();
            } else {

            }
        } else {
            MaterialDialog.Builder builder = MaterialDialogUtils.showLoadingDialog(getActivity());
            loadingDialog = builder.cancelable(false).show();
        }
    }

    public void dismissLoadingDialog() {
        if (loadingDialog != null && loadingDialog.isShowing()) {
            loadingDialog.dismiss();
        }
    }

    /**
     * 跳转页面
     *
     * @param clz 所跳转的目的Activity类
     */
    public void startActivity(Class<?> clz) {
        startActivity(new Intent(getContext(), clz));
    }

    /**
     * 跳转页面
     *
     * @param clz    所跳转的目的Activity类
     * @param bundle 跳转所携带的信息
     */
    public void startActivity(Class<?> clz, Bundle bundle) {
        Intent intent = new Intent(getContext(), clz);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
    }

    public void onError(String errorInfo) {

    }

    /**
     * 跳转容器页面
     *
     * @param canonicalName 规范名 : Fragment.class.getCanonicalName()
     */
    public void startContainerActivity(String canonicalName) {
        startContainerActivity(canonicalName, null);
    }

    /**
     * 跳转容器页面
     *
     * @param canonicalName 规范名 : Fragment.class.getCanonicalName()
     * @param bundle        跳转所携带的信息
     */
    public void startContainerActivity(String canonicalName, Bundle bundle) {
        Intent intent = new Intent(getContext(), ContainerActivity.class);
        intent.putExtra(ContainerActivity.FRAGMENT, canonicalName);
        if (bundle != null) {
            intent.putExtra(ContainerActivity.BUNDLE, bundle);
        }
        startActivity(intent);
    }

    /**
     * =====================================================================
     **/

    //刷新布局
    public void refreshLayout() {
        if (viewModel != null) {
            binding.setVariable(viewModelId, viewModel);
        }
    }

    @Override
    public void initParam() {

    }

    /**
     * 变更模型
     */
    @Override
    public void changeModel() {

    }

    /**
     * 初始化根布局
     *
     * @return 布局layout的id
     */
    public abstract int initContentView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState);

    /**
     * 初始化ViewModel的id
     *
     * @return BR的id
     */
    public abstract int initVariableId();

    /**
     * 初始化ViewModel
     *
     * @return 继承BaseViewModel的ViewModel
     */
    public VM initViewModel() {
        return null;
    }

    @Override
    public void initData() {

    }

    @Override
    public void initViewObservable() {

    }

    public boolean isBackPressed() {
        return false;
    }

    /**
     * 创建ViewModel
     *
     * @param cls
     * @param <T>
     * @return
     */
    public <T extends ViewModel> T createViewModel(Fragment fragment, Class<T> cls) {
        return new ViewModelProvider(this).get(cls);
    }


}
